package logger

import (
	"fmt"
	"runtime"
	"runtime/debug"
)

// -----------------------------------------------------------------------------
// 文件：interface
// 描述：日志使用对外接口模块
// 版本：0.2
// 作者：lg
// 日期：2020-11-15
// 修改：2020-11-15 0.1 lg  新增版本
//      2022-04-13 0.2 lg  修改调用函数formatArgs和formatArgsf参数
// ----------------------------------------------------------------------------

func formatArgsf(option string, skip int, template string, args ...interface{}) (string, []interface{}) {
	var prfix []interface{}
	if option == "debug" {
		stack := string(debug.Stack())
		template = template + "\n%s"
		return template, append(args, stack)
	}
	pc, file, line, ok := runtime.Caller(skip)
	if ok {
		if option == "function" {
			funcName := runtime.FuncForPC(pc).Name()
			prfix = append(prfix, funcName)
			template = "%s: " + template
		} else if option == "source" {
			prfix = append(prfix, file, line)
			template = "%s:%d: " + template
		} else {
			panic("获取调用栈失败:输入参数有误(function,source)")
		}
		return template, append(prfix, args...)
	}
	panic("获取调用栈信息失败")
}

func formatArgs(option string, skip int, args ...interface{}) []interface{} {
	var prfix []interface{}
	if option == "debug" {
		stack := string(debug.Stack())
		return append(args, "\n"+stack)
	}
	pc, file, line, ok := runtime.Caller(skip)
	if ok {
		if option == "function" {
			funcName := runtime.FuncForPC(pc).Name()
			prfix = append(prfix, funcName+": ")
		} else if option == "source" {
			prfix = append(prfix, fmt.Sprintf("%s:%d: ", file, line))
		} else {
			panic("获取调用栈失败:输入参数有误(function,source)")
		}
		return append(prfix, args...)
	}
	panic("获取调用栈信息失败")
}

// ------------------------------ formatArgsf 2 -------------------------------
// Debugf function print debug format log
func Debugf(template string, args ...interface{}) {
	template, args = formatArgsf("function", 2, template, args...)
	sugar.Debugf(template, args...)
}

// Infof function print info format log
func Infof(template string, args ...interface{}) {
	template, args = formatArgsf("function", 2, template, args...)
	sugar.Infof(template, args...)
}

// Warnf function print warn format log
func Warnf(template string, args ...interface{}) {
	template, args = formatArgsf("function", 2, template, args...)
	sugar.Warnf(template, args...)
}

// Errorf function print error format log
func Errorf(template string, args ...interface{}) {
	template, args = formatArgsf("function", 2, template, args...)
	sugar.Errorf(template, args...)
}

// Panicf function print panic format log
func Panicf(template string, args ...interface{}) {
	template, args = formatArgsf("debug", 2, template, args...)
	sugar.Panicf(template, args...)
}

// Fatalf function print fatal format log
func Fatalf(template string, args ...interface{}) {
	template, args = formatArgsf("debug", 2, template, args...)
	sugar.Fatalf(template, args...)
}

// ----------------------------- formatArgs 2 ----------------------------------
// Debug function print debug log
func Debug(args ...interface{}) {
	args = formatArgs("function", 2, args...)
	sugar.Debug(args...)
}

// Info function print info log
func Info(args ...interface{}) {
	args = formatArgs("function", 2, args...)
	sugar.Info(args...)
}

// Warn function print warn log
func Warn(args ...interface{}) {
	args = formatArgs("function", 2, args...)
	sugar.Warn(args...)
}

// Error function print error log
func Error(args ...interface{}) {
	args = formatArgs("function", 2, args...)
	sugar.Error(args...)
}

// Panic function print panic log
func Panic(args ...interface{}) {
	args = formatArgs("debug", 2, args...)
	sugar.Panic(args...)
}

// Fatal function print fatal log
func Fatal(args ...interface{}) {
	args = formatArgs("debug", 2, args...)
	sugar.Fatal(args...)
}

// ------------------------------ formatArgsf 3 -------------------------------
// Debugf function print debug format log
func PDebugf(template string, args ...interface{}) {
	template, args = formatArgsf("function", 3, template, args...)
	sugar.Debugf(template, args...)
}

// Infof function print info format log
func PInfof(template string, args ...interface{}) {
	template, args = formatArgsf("function", 3, template, args...)
	sugar.Infof(template, args...)
}

// Warnf function print warn format log
func PWarnf(template string, args ...interface{}) {
	template, args = formatArgsf("function", 3, template, args...)
	sugar.Warnf(template, args...)
}

// Errorf function print error format log
func PErrorf(template string, args ...interface{}) {
	template, args = formatArgsf("function", 3, template, args...)
	sugar.Errorf(template, args...)
}

// Panicf function print panic format log
func PPanicf(template string, args ...interface{}) {
	template, args = formatArgsf("debug", 3, template, args...)
	sugar.Panicf(template, args...)
}

// Fatalf function print fatal format log
func PFatalf(template string, args ...interface{}) {
	template, args = formatArgsf("debug", 3, template, args...)
	sugar.Fatalf(template, args...)
}

// ----------------------------- formatArgs 3 ----------------------------------
// Debug function print debug log
func PDebug(args ...interface{}) {
	args = formatArgs("function", 3, args...)
	sugar.Debug(args...)
}

// Info function print info log
func PInfo(args ...interface{}) {
	args = formatArgs("function", 3, args...)
	sugar.Info(args...)
}

// Warn function print warn log
func PWarn(args ...interface{}) {
	args = formatArgs("function", 3, args...)
	sugar.Warn(args...)
}

// Error function print error log
func PError(args ...interface{}) {
	args = formatArgs("function", 3, args...)
	sugar.Error(args...)
}

// Panic function print panic log
func PPanic(args ...interface{}) {
	args = formatArgs("debug", 3, args...)
	sugar.Panic(args...)
}

// Fatal function print fatal log
func PFatal(args ...interface{}) {
	args = formatArgs("debug", 3, args...)
	sugar.Fatal(args...)
}

// Logf function print format log
func Logf(template string, args ...interface{}) {
	sugar.Infof(template, args...)
}

// Log function print log
func Log(args ...interface{}) {
	sugar.Info(args...)
}
